<?php

namespace app\admin\controller\mall;

use app\common\lib\Status;
use app\common\lib\Tree;
use app\common\model\MallCate;
use app\common\model\MallGoods;
use app\common\model\MallGoodsSku;
use app\common\model\MallSpecsValue;
use app\common\model\mysql\MallSpecs;
use app\common\controller\AdminController;
use app\common\lib\Show;
use EasyAdmin\annotation\ControllerAnnotation;
use EasyAdmin\annotation\NodeAnotation;
use think\App;
use think\Exception;
use think\facade\Log;

/**
 * @ControllerAnnotation(title="商品列表")
 */
class Goods extends AdminController
{

    use \app\admin\traits\Curd;

    public function __construct(App $app)
    {
        parent::__construct($app);

        $this->model = new \app\common\model\MallGoods();

        $this->assign('getStatusList', $this->model->getStatusList());
    }


    /**
     * @NodeAnotation(title="列表")
     */
    public function index()
    {
        if ($this->request->isAjax()) {
            if (input('selectFields')) {
                return $this->selectList();
            }
            list($page, $limit, $where, $where1) = $this->buildTableParames();

            $count = $this->model
                ->where($where)
                ->where($where1)
                ->count();

            $list = $this->model
                ->where($where)
                ->where($where1)
                ->page($page, $limit)
                ->order($this->sort)
                ->select();
            $sql = $this->model->getLastSql();
            foreach ($list as $k => $v) {
                if ($v['cate_ids']) {
                    $cate_ids = explode(',', $v['cate_ids']);
                    $catinfo = (new MallCate())->where("id", '=', $cate_ids[0])->find();
                    $list[$k]['catname'] = $catinfo['title'];
                } else {
                    $list[$k]['catname'] = '--';
                }
            }
            $data = [
                'code' => 0,
                'msg' => '',
                'count' => $count,
                'data' => $list,
                'sql' => $sql
            ];
            return json($data);
        }
        $treeList = $this->getTreeCate();
        $treeLists = [];
        foreach ($treeList as $kk => $vv) {
            $treeLists[$kk]['id'] = $vv['id'];
            $treeLists[$kk]['title'] = $vv['title'];
        }
        $treeLists = array_column($treeLists, 'title', 'id');

        $this->assign('catlist', json_encode($treeLists));
        return $this->fetch();
    }

    /**
     * @return array|\int[][]|\string[][]
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    protected function getTreeCate(): array
    {
        $lists = (new MallCate())->field('id,pid,title')->where('status', 1)
            ->order('sort desc,id desc')
            ->select()
            ->toArray();
        return Tree::getInstance()->getPidMenuList(0, $lists);
    }

    /**
     * @NodeAnotation(title="获取商品列表")
     * @return array|\think\response\Json
     */
    public function getGoodsByListNameInfo()
    {
        $where = [

        ];
        try {
            $lists = (new MallGoods())->getBaseByNormalList($where, "id as value,title as name");
        } catch (\Exception $exception) {
            return Show::json_show(Status::status_error, "查询商品失败");
        }
        return Show::json_show(Status::status_normal, "ok", $lists);
    }

    public function getGoodsBySpecs()
    {
        $goods_id = $this->request->param('goods_id', 0, 'intval');
        if ($goods_id == 0) {
            return Show::json_show(Status::status_error, "请选择商品");
        }
        //查询规格
        try {
            $result = (new MallGoodsSku())->getGoodsSkuBySpecs($goods_id);
        } catch (\Exception $e) {
            return Show::json_show(Status::status_error, "操作失败");
        }
        return Show::json_show(Status::status_normal, "ok", $result);
    }

    public function dialog()
    {
        return $this->fetch();
    }

    public function add()
    {
        if ($this->request->isPost()) {
            $post = $this->request->post();
            $rule = [
                'cate_ids|分类' => 'require',
                'title|商品名称' => 'require',
                'logo|商品logo' => 'require',
                'images|商品图片' => 'require',
                'describe|商品描述' => 'require',
                'specifications|商品规格' => 'require',
            ];
            $this->validate($post, $rule);
            //判断规格
            if ($post['specifications'] == 0) {
                if (empty($post['market_price'])) {
                    $this->error("请输入市场价");
                }
                if (empty($post['price'])) {
                    $this->error("请输入卖价");
                }
                if (empty($post['stock'])) {
                    $this->error("请输入库存");
                }
                if (empty($post['total_stock'])) {
                    $this->error("请输入总库存");
                }
            } else {
                if (empty($post['skus'])) {
                    $this->error("请添加规格");
                }
            }
            $this->model->startTrans();
            try {
                //添加入库
                if ($post['specifications'] == 0) {
                    //单品
                    $insId = $this->model->save($post);
                    if ($insId) {
                        $p_id = $this->model->id;
                        $skus = [
                            "goods_id" => $p_id,
                            "stock" => $post['stock'],
                            "image" => $post['logo'],
                            "market_price" => $post['market_price'],
                            "price" => $post['price'],
                            "is_dan" => 1,
                            "cost_price" => $post['price'],
                        ];
                        $saveIds = (new MallGoodsSku())->insertGetId($skus);
                        if ($saveIds) {
                            $update_data = [
                                "sku_id" => $saveIds,
                            ];
                            $result = $this->model->updateDataSave($p_id, $update_data);

                        } else {
                            throw new Exception("添加sku表失败");
                        }

                    } else {
                        throw new Exception("添加商品表失败");
                    }
                } else {
                    //多规格
                    //先添加商品 然后再添加skus
//                    $post['stock'] = $post['skus'][1]['stock'];
//                    $post['price'] = $post['skus'][1]['price'];
//                    $post['market_price'] = $post['skus'][1]['market_price'];
//                    $post['cost_price'] = $post['skus'][1]['cost_price'];
//                    $post['total_stock'] = array_sum(array_column($post['skus'], 'stock'));

                    $insId = $this->model->save($post, true);
                    if ($insId) {
                        $skus = [];
                        $res_id = $this->model->id;
                        foreach ($post['skus'] as $k => $v) {
                            if (empty($picture)) {
                                $picture = $post['logo'];
                            }
                            $skus[] = [
                                "image" => $picture,
                                "goods_id" => $res_id,
                                "stock" => $v['stock'],
                                "price" => $v['price'],
                                "market_price" => $v['market_price'],
                                "cost_price" => $v['cost_price'],
                                "status" => $v['status'],
                                "specs_value_ids" => $k
                            ];

                        }
                        if (empty($skus)) {
                            throw new Exception("系统内部错误");
                        }
                        //添加库存
                        $res = (new MallGoodsSku())->saveAll($skus);
                        $update_data = [];
                        if ($res) {
                            $update_data['stock'] = array_sum(array_column($skus, 'stock'));
                            $update_data['price'] = $skus[0]['price'];
                            $update_data['market_price'] = $skus[0]['market_price'];
                            $update_data['cost_price'] = $skus[0]['cost_price'];
                            $update_data['total_stock'] = array_sum(array_column($skus, 'stock'));
                            $update_data['sku_id'] = $res[0]['id'];
                        }
                        $result = $this->model->updateDataSave($res_id, $update_data);
                    }
                }
                $this->model->commit();
            } catch (\Exception $e) {
                Log::error($e->getMessage() . " " . $e->getFile() . " " . $e->getLine());
                $this->model->rollback();
                $this->error("内部发生错误");
            }
            if ($result) {
                $this->success("操作成功");
            } else {
                $this->error("操作失败");
            }
        }
        return $this->fetch();
    }

    /**
     * @param $id
     * @return mixed
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function edit($id)
    {
        if ($this->request->isPost()) {
            $post = $this->request->post();
//            dump($post);exit();
            $rule = [
                'cate_ids|分类' => 'require',
                'title|商品名称' => 'require',
                'logo|商品logo' => 'require',
                'images|商品图片' => 'require',
                'describe|商品描述' => 'require',
                'specifications|商品规格' => 'require',
            ];
            $this->validate($post, $rule);
            //判断规格
            if ($post['specifications'] == 0) {
                if (empty($post['market_price'])) {
                    $this->error("请输入市场价");
                }
                if (empty($post['price'])) {
                    $this->error("请输入卖价");
                }
                if (empty($post['stock'])) {
                    $this->error("请输入库存");
                }
                if (empty($post['total_stock'])) {
                    $this->error("请输入总库存");
                }
            } else {
                if (empty($post['skus'])) {
                    $this->error("请添加规格");
                }
            }
            $post['id'] = $id;

            unset($post['file']);
            $this->model->startTrans();
            try {
                //添加入库
                if ($post['specifications'] == 0) {
                    //单品
                    $update_goods = [
                        "cate_ids" => $post['cate_ids'],
                        "title" => $post['title'],
                        "thumb_title" => $post['thumb_title'],
                        "logo" => $post['logo'],
                        "video" => $post['video'],
                        "specifications" => $post['specifications'],
                        "is_appoint" => $post['is_appoint'],
                        "images" => $post['images'],
                        "describe" => $post['describe'],
                        "sort" => $post['sort'],
                        "remark" => $post['remark'],
                        "market_price" => $post['market_price'],
                        "cost_price" => $post['cost_price'],
                        "price" => $post['price'],
                        "sales" => $post['sales'],
                        "update_time" => time()
                    ];
                    $insId = $this->model->where('id', $post['id'])->update($update_goods);
                    if ($insId) {
                        $p_id = $post['id'];
                        $skus = [
                            "goods_id" => $p_id,
                            "stock" => $post['stock'],
                            "image" => $post['logo'],
                            "market_price" => $post['market_price'],
                            "price" => $post['price'],
                            "is_dan" => 1,
                            "cost_price" => $post['price'],
                        ];
                        (new MallGoodsSku())->where('goods_id', $post['id'])->delete();
                        $saveIds = (new MallGoodsSku())->insertGetId($skus);
                        if ($saveIds) {
                            $update_data = [
                                "sku_id" => $saveIds,
                            ];
                            $result = $this->model->updateDataSave($p_id, $update_data);

                        } else {
                            throw new Exception("编辑sku表失败");
                        }

                    } else {
                        throw new Exception("编辑商品表失败");
                    }
                } else {
                    //多规格
                    $update_goods = [
                        "cate_ids" => $post['cate_ids'],
                        "title" => $post['title'],
                        "thumb_title" => $post['thumb_title'],
                        "logo" => $post['logo'],
                        "video" => $post['video'],
                        "specifications" => $post['specifications'],
                        "is_appoint" => $post['is_appoint'],
                        "images" => $post['images'],
                        "describe" => $post['describe'],
                        "sort" => $post['sort'],
                        "remark" => $post['remark'],
                        'update_time' => time()
                    ];
                    $insId = $this->model->where('id', $post['id'])->update($update_goods);

                    if ($insId) {
                        $skus = [];
                        $res_id = $post['id'];
                        foreach ($post['skus'] as $k => $v) {
                            if (empty($picture)) {
                                $picture = $post['logo'];
                            }
                            $skus[] = [
                                "image" => $picture,
                                "goods_id" => $res_id,
                                "stock" => $v['stock'],
                                "price" => $v['price'],
                                "market_price" => $v['market_price'],
                                "cost_price" => $v['cost_price'],
                                "specs_value_ids" => $k
                            ];
                        }
                        if (empty($skus)) {
                            throw new Exception("系统内部错误");
                        }

                        //添加库存
                        $ret = (new MallGoodsSku())->where([['goods_id', '=', $post['id']]])->delete();
                        if (!$ret) {
                            throw new Exception("发生错误");
                        }
                        $res = (new MallGoodsSku())->saveAll($skus);
                        $update_data = [];
                        if ($res) {
                            $update_data['stock'] = array_sum(array_column($skus, 'stock'));
                            $update_data['price'] = $skus[0]['price'];
                            $update_data['market_price'] = $skus[0]['market_price'];
                            $update_data['cost_price'] = $skus[0]['cost_price'];
                            $update_data['total_stock'] = array_sum(array_column($skus, 'stock'));
                            $update_data['sku_id'] = $res[0]['id'];
                        }
                        $result = $this->model->updateDataSave($res_id, $update_data);
                    }
                }
                $this->model->commit();
            } catch (\Exception $e) {
                Log::error($e->getMessage() . " " . $e->getFile() . " " . $e->getLine());
                $this->model->rollback();
                $this->error($e->getMessage());
            }
            $this->success("操作成功");
        }
        $id = $this->request->param('id', '', 'intval');
        $row = $this->model->find($id);
        if ($row['status'] == 1) {
            $this->error("上架商品禁止编辑");
        }
        empty($row) && $this->error('数据不存在');
        if ($this->request->isPost()) {
            $post = $this->request->post();
            $rule = [];
            $this->validate($post, $rule);
            try {
                $save = $row->save($post);
            } catch (\Exception $e) {
                $this->error('保存失败');
            }
            $save ? $this->success('保存成功') : $this->error('保存失败');
        }
        $row['describe'] = htmlspecialchars_decode($row['describe']);
        $this->assign('row', $row);
        //查询sku
        $sku = (new MallGoodsSku())->where("goods_id", $id)
            ->select()
            ->toArray();
        $tree = [];
        if (!empty($sku)) {
            $skus = [];
            foreach ($sku as $v) {
                $skus[] = explode('-', $v['specs_value_ids']);
            }
            $sku_value = [];
            if (!empty($skus)) {
                foreach ($skus as $v) {
                    foreach ($v as $item) {
                        $sku_value[] = $item;
                    }
                }
            }
            $value = (new MallSpecsValue())->alias('c')
                ->field('c.id,c.title,c.specs_id,b.title as specs_title')
                ->join('mall_specs b', 'b.id = c.specs_id')
                ->where('c.id', 'in', $sku_value)
                ->select()->toArray();
            //$this->getTreeSpecs($value);
            $specs_values = [];
            $specs_value = (new MallSpecsValue())
                ->alias('c')
                ->field('c.id,c.title,c.specs_id,b.title as specs_title')
                ->join('mall_specs b', 'b.id = c.specs_id')
                ->where('specs_id', 'in', array_column($value, 'specs_id'))
                ->select()
                ->toArray();
            foreach ($specs_value as $k => $v) {
                $specs_values[$k] = $v;
                $specs_values[$k]['checked'] = '';
                foreach ($value as $j) {
                    if ($v['specs_id'] == $j['specs_id'] && $v['id'] == $j['id']) {
                        $specs_values[$k]['checked'] = 'checked';
                    }
                }
            }
            $tree = $this->getTreeSpecs($specs_values);
        }
        $sku_data = [];
        foreach ($sku as $value) {
            $sku_data[$value['specs_value_ids']] = $value;
        }

        return $this->fetch('', [
            "tree" => $tree,
            "sku" => $sku_data,
            "id" => $id
        ]);
    }

    public function getGoodscates()
    {
        $id = $this->request->param('id', 0, 'intval');
        if ($id == 0) {
            $this->error("发生错误");
        }
        $goods = $this->model->find($id);
        if (!$goods) {
            $this->error("商品不存在");
        }
        $cateids = [];
        if ($goods['cate_ids']) {
            $cate_ids = explode(',', $goods['cate_ids']);
            foreach ($cate_ids as $k => $cate_id) {
                $catinfo = (new MallCate())->field('id,title')->where("id='$cate_id'")->find();
                $cateids[$k]['value'] = $cate_id;
                $cateids[$k]['name'] = $catinfo['title'];
            }
        }

        $sku = (new MallGoodsSku())->where("goods_id", $id)
            ->select()
            ->toArray();
        $sku_data = [];
        foreach ($sku as $value) {
            $sku_data[$value['specs_value_ids']] = $value;
        }

        $this->success('ok', ['cateids' => $cateids, 'sku_data' => $sku_data]);
    }


    protected function getTreeSpecs(array $data = [])
    {
        if (empty($data)) {
            return [];
        }
//        dump($data);exit();
        $lists = [];
        foreach ($data as $v) {
            if (!isset($lists[$v['specs_id']])) {
                $lists[$v['specs_id']] = $v;
            }
            $lists[$v['specs_id']]['child'][] = $v;
        }
        return $lists;
    }

    public function getGoodsSkus()
    {
        $id = $this->request->param('id', 0, 'intval');
        if ($id == 0) {
            $this->error("发生错误");
        }
        $sku = (new MallGoodsSku())->where("goods_id", $id)
            ->select()
            ->toArray();
        $sku_data = [];
        foreach ($sku as $value) {
            $sku_data[$value['specs_value_ids']] = $value;
        }
        $this->success('ok', $sku_data);
    }
}